///************************************************************************
/// <copyrigth>2018-2019 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// You can get the current time and convert time to be string or from string
///</describe>
/// <date>2021/1/31</date>
///***********************************************************************
#ifndef DATETIME_H
#define DATETIME_H

#include <time.h>
#include <iostream>
#include <string>
#include "boost/date_time/posix_time/posix_time.hpp"

namespace SystemTool
{
	namespace Clock
	{
		enum DateRegion
		{
			// Local time
			DATE_REGION_LOCAL = 0,

			// UTC time
			DATE_REGION_UTC
		};

		class DateTime
		{
		public:
			// Construct a date time
			DateTime(unsigned int iYear = 0, 
				unsigned int iMonth = 0, 
				unsigned int iDay = 0,
				unsigned int iHour = 0,
				unsigned int iMin = 0,
				unsigned int iSeconds = 0,
				unsigned int iMilliseconds = 0);

			// Destory the date time
			~DateTime();

			// Copy the date time
			DateTime(const DateTime& other);

			// Assign the date time
			DateTime& operator=(const DateTime& other);

			// Is two date time equaled
			bool operator==(const DateTime& other);

			// Convert the date time to time_t
			time_t ToTime_t();

			// To string
			std::string ToString(DateRegion eDateRegion = DATE_REGION_LOCAL);

			// Get current date time
			static DateTime Now(DateRegion eDateRegion = DATE_REGION_LOCAL);

			// Get the date time from the time_t
			static DateTime FromTime_t(time_t TimeDuration);

			// Get the date time from the string (local format is: yyyy-MM-dd hh:mm:ss and iso format: yyyyMMddThhmmss)
			static DateTime FromString(std::string strTime, DateRegion eDateRegion = DATE_REGION_LOCAL);

			// Get a year
			inline unsigned int GetYear() const
			{
				return m_iYear;
			}

			// Get a month
			inline unsigned int GetMonth() const
			{
				return m_iMonth;
			}

			// Get a day
			inline unsigned int GetDay() const
			{
				return m_iDay;
			}

			// Get a hour
			inline unsigned int GetHour() const
			{
				return m_iHour;
			}

			// Get a minute
			inline unsigned int GetMinute() const
			{
				return m_iMinute;
			}

			// Get seconds
			inline unsigned int GetSeconds() const
			{
				return m_iSeconds;
			}

			// Get a milliseconds
			inline unsigned int GetMilliseconds() const
			{
				return m_iMilliseconds;
			}

		private:
			// PTime to datetime
			static DateTime ToDateTime(boost::posix_time::ptime& t);

			// Datetime to ptime
			static boost::posix_time::ptime ToBoostTime(DateTime& t);

		private:
			// Get the disposed status
			inline bool GetDisposed() const
			{
				return m_bDisposed;
			}

			// Set the disposed status
			inline void SetDisposed(bool bDisposed)
			{
				m_bDisposed = bDisposed;
			}

			// Set the year
			inline void SetYear(unsigned int iYear)
			{
				m_iYear = iYear;
			}

			// Set the month
			inline void SetMonth(unsigned int iMonth)
			{
				m_iMonth = iMonth;
			}

			// Set the day
			inline void SetDay(unsigned int iDay)
			{
				m_iDay = iDay;
			}

			// Set the hour
			inline void SetHour(unsigned int iHour)
			{
				m_iHour = iHour;
			}

			// Set the minute
			inline void SetMinute(unsigned int iMinute)
			{
				m_iMinute = iMinute;
			}

			// Set the seconds
			inline void SetSeconds(unsigned int iSeconds)
			{
				m_iSeconds = iSeconds;
			}

			// Set the milliseconds
			inline void SetMilliseconds(unsigned int iMilliseconds)
			{
				m_iMilliseconds = iMilliseconds;
			}

		private:
			// Year
			unsigned int m_iYear;

			// Month
			unsigned int m_iMonth;

			// Day
			unsigned int m_iDay;

			// Hour
			unsigned int m_iHour;

			// Minute
			unsigned int m_iMinute;

			// Seconds
			unsigned int m_iSeconds;

			// Millseconds
			unsigned int m_iMilliseconds;

			// Disposed the status
			bool m_bDisposed;
		};
	}
}

#endif // DATETIME_H
